package com.kabigon.tiny.utils;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.kabigon.tiny.anno.BankApiField;
import com.kabigon.tiny.pojo.AbstractApi;
import com.kabigon.tiny.pojo.CreateUserApi;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @author xu.biao
 * @version v1.0
 * @Package com.kabigon.tiny.utils
 * @data 2022/12/11 16:58
 */
@Slf4j
public class BankApi {

    private static AbstractApi remoteCall(AbstractApi api) {
        long begin = System.currentTimeMillis();

        com.kabigon.tiny.anno.BankApi bankApi = api.getClass().getAnnotation(com.kabigon.tiny.anno.BankApi.class);
        String url = bankApi.url();
        StringBuilder stringBuilder = new StringBuilder();
        Arrays.stream(api.getClass().getDeclaredFields())
                // 查找标记了注解的字段
                .filter(field -> field.isAnnotationPresent(BankApiField.class))
                // 根据注解中的order对字段排序
                .sorted(Comparator.comparingInt(value -> value.getAnnotation(BankApiField.class).order()))
                // 设置字段可以访问
                .peek(field -> field.setAccessible(true))
                .forEach(field -> {
                    // 获得注解
                    BankApiField bankApiField = field.getAnnotation(BankApiField.class);
                    Object value = null;
                    try {
                        // 反射获取字段值
                        value = field.get(api);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }

                    // 根据字段类型以正确的填充方式格式化字符串
                    switch (bankApiField.type()) {
                        case "S":
                            stringBuilder.append(StrUtil.format("%-{}s{}", bankApiField.length(), value.toString()).replace(' ', '_'));
                            break;
                        case "N":
                            stringBuilder.append(StrUtil.format("%{}s{}", bankApiField.length(), value.toString()).replace(' ', '0'));
                            break;
                        case "M":
                            if (!(value instanceof BigDecimal)) {
                                throw new RuntimeException(StrUtil.format("{} 的 {} 必须是BigDecimal", api, field));
                            }
                            stringBuilder.append(StrUtil.format("%0{}s{}", bankApiField.length(), NumberUtil.roundDown((BigDecimal) value, 2)));
                            break;
                        default:
                            break;
                    }

                });
        // 签名逻辑
        String md5 = DigestUtil.md5Hex(stringBuilder.toString());
        ReflectUtil.setFieldValue(api, "md5", md5);
        stringBuilder.append(md5);
        String params = stringBuilder.toString();

        // 发请求
        log.info("调用银行ApI {} url:{} 参数：{} 耗时：{}ms", bankApi.desc(), bankApi.url(), params, System.currentTimeMillis() - begin);
        return api;


    }

    public static void main(String[] args) {
        CreateUserApi api = new CreateUserApi();
        api.setName("   xu.biao");
        api.setIdentity("32108819990221331");
        api.setMobile(" 17696830643");
        api.setAge(21);

        AbstractApi resut = remoteCall(api);
        System.out.println(StrUtil.format("result: {}", resut.toString()));
    }
}
